//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

package upgrade

import (
	"context"
	"math"

	"atomgit.com/openlinksaas/api-server/dao"
	"atomgit.com/openlinksaas/api-server/dao/idea_dao"
	"atomgit.com/openlinksaas/api-server/dao/project_dao"
	"atomgit.com/openlinksaas/proto-gen-go.git/project_idea_api"
	"github.com/google/uuid"
	"go.mongodb.org/mongo-driver/mongo"
)

type UpToVer30 struct{}

func (up *UpToVer30) Exec(ctx context.Context) error {
	prjList, err := project_dao.ProjectInfoDao.ListAll(ctx, 0, math.MaxInt64)
	if err != nil {
		return err
	}
	for _, prj := range prjList {
		err = up.fixIdeaGroup(ctx, prj)
		if err != nil {
			return err
		}
	}
	return dao.VersionDao.Set(ctx, dao.VERSION_KEY_SCHEMA, 30)
}

func (up *UpToVer30) fixIdeaGroup(ctx context.Context, projectItem *project_dao.ProjectInfoDbItem) error {
	if projectItem.DefaultIdeaGroupId != "" {
		return nil
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		return err
	}
	defer dao.EndSession(dbSess)

	_, err = dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		projectItem.DefaultIdeaGroupId = uuid.NewString()
		err = idea_dao.IdeaDao.FixIdeaGroup(sessCtx, projectItem.ProjectId, projectItem.DefaultIdeaGroupId)
		if err != nil {
			return nil, err
		}
		count, err := idea_dao.IdeaDao.Count(sessCtx, projectItem.ProjectId, &project_idea_api.ListIdeaParam{
			FilterByGroupId: true,
			GroupId:         projectItem.DefaultIdeaGroupId,
		})
		if err != nil {
			return nil, err
		}
		err = idea_dao.IdeaGroupDao.Insert(sessCtx, &idea_dao.IdeaGroupDbItem{
			IdeaGroupId:  projectItem.DefaultIdeaGroupId,
			Name:         "项目知识点",
			ProjectId:    projectItem.ProjectId,
			Weight:       math.MaxUint32,
			IdeaCount:    count,
			CreateUserId: projectItem.OwnerUserId,
			UpdateUserId: projectItem.OwnerUserId,
			CreateTime:   projectItem.CreateTime,
			UpdateTime:   projectItem.CreateTime,
		})
		if err != nil {
			return nil, err
		}
		err = project_dao.ProjectInfoDao.UpdateProject(sessCtx, projectItem)
		if err != nil {
			return nil, err
		}
		return nil, nil
	})
	return err
}
